home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 4
/
Aminet 4 - November 1994.iso
/
aminet
/
comm
/
ums
/
ums109_1.lha
/
Tools
/
UMSMM.LHA
/
UMSMM
/
UMSMM.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-08
|
21KB
|
785 lines
/*
* UMSMailMon - UMS Mail Monitor
*
* Monitors an UMS messagebase for unread mail.
*
* Based on Sabot V1.7 by Scott Ellis
*
*************************************************************************
*
* Copyright (C) 1994 Thomas Schwarz
* <blacky@bmagic.mayn.sub.de>
* <Thomas_Schwarz@wue.maus.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*************************************************************************
*
* History:
*
* V1.0 + Initial release
* V1.1 + Lost some memory when started from workbench
* + If the number of new mails changed, the new number was not displayed
* + Several cleanups
* + Two new icons (mt*.info) contributed by Ralf Garbade. Thanks Ralf!
*/
#include "UMSMM.h"
#define BIGSTRING 255
#define VERSION "1.1"
STRPTR VersionID = "\0$VER: UMSMailMon "VERSION" (" __COMMODORE_DATE__ ")";
enum args
{
NAME,
PASSWORD,
SERVER,
MAIL,
NOMAIL,
NOTIFY,
TIMER,
XPOS,
YPOS,
CLICKCOMMAND,
CLICKSTACK,
MAILCOMMAND,
MAILSTACK,
DROPCOMMAND,
DROPSTACK
};
enum active_args
{
LOGIN,
NONE,
NEW
};
struct WBStartup *WBStart = NULL;
UMSUserAccount MyUMSAccount = 0;
extern struct Library *UMSBase;
extern struct Library *IconBase;
extern struct Library *WorkbenchBase;
struct MsgPort *MyPort = NULL;
struct AppIcon *MyAppIcon = NULL;
struct DiskObject *MyImage = NULL;
struct NotifyRequest *MyNoteReq = NULL;
ULONG MyNoteSigNum = -1L;
struct timerequest *TimeReq = NULL;
ULONG MyTimerSig = 0;
STRPTR Name = NULL, Password = NULL, Server = NULL;
STRPTR HaveMail = NULL;
STRPTR NoMail = NULL;
STRPTR Watch = NULL;
STRPTR ClickComName = NULL;
STRPTR MailComName = NULL;
STRPTR DropComName = NULL;
ULONG ClickComStack = 4096;
ULONG MailComStack = 4096;
ULONG DropComStack = 4096;
ULONG XPos = 0;
ULONG YPos = 0;
ULONG Timer = 0;
LONG UnreadMails = 0;
LONG PrevUnreadMails = 0;
USHORT Active = LOGIN;
VOID wbmain(struct WBStartup *);
ULONG main(ULONG, STRPTR *);
BOOL AddIcon(struct MsgPort *, struct DiskObject *);
VOID KillIcon(VOID);
BOOL GetImage(STRPTR);
VOID KillImage(VOID);
VOID ChangeIcon(VOID);
VOID DoInfo(VOID);
VOID Compare(VOID);
BOOL Parse(LONG, STRPTR *);
VOID DoCommand(STRPTR, ULONG);
BOOL MakeVars(VOID);
VOID FreeVars(VOID);
VOID BeginNotify(VOID);
BOOL OpenTimer(VOID);
VOID CloseTimer(VOID);
VOID chkabort(VOID)
{
}
/// "wbmain"
VOID wbmain(struct WBStartup *wbs)
{
WBStart = wbs;
main(0, NULL);
}
///
/// "main"
ULONG main(ULONG argc, STRPTR *argv)
{
struct AppMessage *appmsg = NULL;
BOOL going = TRUE;
ULONG mysig = 0;
ULONG myportsig = 0;
ULONG waitsigs = 0;
LONG count = 0;
if (!MakeVars())
{
FreeVars();
return 20;
}
if (!Parse(argc, argv))
{
FreeVars();
return 20;
}
if(Timer)
{
if(!OpenTimer())
{
CloseTimer();
FreeVars();
return 20;
}
}
if (MyPort = CreatePort(NULL, 0))
{
myportsig = (1L << MyPort->mp_SigBit);
if (GetImage(NoMail))
{
if (AddIcon(MyPort, MyImage))
{
/* log into UMS system */
if (MyUMSAccount = UMSRLogin(Server, Name, Password))
{
DoInfo();
if (UnreadMails) /* Show appropriate icon on startup */
Active = NEW;
else
Active = NONE;
ChangeIcon();
if(strlen(Watch))
BeginNotify();
waitsigs = myportsig | SIGBREAKF_CTRL_C;
if(Timer)
waitsigs |= MyTimerSig;
if(MyNoteReq)
waitsigs |= (1L << MyNoteSigNum);
while (going)
{
mysig = Wait(waitsigs);
if (mysig & SIGBREAKF_CTRL_C)
going = FALSE;
if (Timer && (mysig & MyTimerSig))
{
WaitIO((struct IORequest *)TimeReq);
DoInfo();
Compare();
TimeReq->tr_time.tv_secs = Timer;
TimeReq->tr_time.tv_micro = 0;
SendIO((struct IORequest *)TimeReq);
}
if (MyNoteReq && (mysig & (1L << MyNoteSigNum)))
{
DoInfo();
Compare();
}
if (mysig & myportsig)
{
while(appmsg = (struct AppMessage *)GetMsg(MyPort))
{
if (appmsg->am_NumArgs == 0)
{
if (*ClickComName)
{
if(!strcmp(ClickComName, "QUIT"))
going = FALSE;
else
DoCommand(ClickComName, ClickComStack);
}
}
else if (appmsg->am_NumArgs > 0)
{
if (*DropComName)
{
TEXT dropname[BIGSTRING], droptemp[2 * BIGSTRING];
count = appmsg->am_NumArgs;
while (count)
{
--count;
if (NameFromLock(appmsg->am_ArgList[count].wa_Lock, dropname, BIGSTRING))
{
if (AddPart(dropname, appmsg->am_ArgList[count].wa_Name, BIGSTRING))
{
sprintf(droptemp, "%s %s", DropComName, dropname);
DoCommand(droptemp, DropComStack);
}
}
strcpy(droptemp, "");
strcpy(dropname, "");
}
}
}
ReplyMsg((struct Message *)appmsg);
}
}
}
if(MyNoteReq)
{
EndNotify(MyNoteReq);
FreeSignal(MyNoteSigNum);
FreeVec(MyNoteReq);
}
UMSLogout(MyUMSAccount);
}
KillIcon();
}
KillImage();
}
while(appmsg = (struct AppMessage *)GetMsg(MyPort))
ReplyMsg((struct Message *)appmsg);
DeletePort(MyPort);
}
if(Timer)
{
if(!CheckIO((struct IORequest *)TimeReq))
AbortIO((struct IORequest *)TimeReq);
WaitIO((struct IORequest *)TimeReq);
CloseTimer();
}
FreeVars();
return 0;
}
///
/// "AddIcon"
BOOL AddIcon(struct MsgPort *port, struct DiskObject *image)
{
TEXT iconname[32];
if (Active == LOGIN)
strcpy(iconname, "Logging in...");
else
{
if(UnreadMails == 1)
sprintf(iconname, "%d New Mail!", UnreadMails);
else if(UnreadMails)
sprintf(iconname, "%d New Mails!", UnreadMails);
else
strcpy(iconname, "No Mail Today");
}
if (MyAppIcon = AddAppIconA(0, 0, iconname, port, NULL, image, NULL))
return TRUE;
return FALSE;
}
///
/// "KillIcon"
VOID KillIcon(VOID)
{
RemoveAppIcon(MyAppIcon);
}
///
/// "GetImage"
BOOL GetImage(STRPTR name)
{
if (MyImage = GetDiskObject(name))
{
MyImage->do_Type = NULL;
MyImage->do_CurrentX = XPos;
MyImage->do_CurrentY = YPos;
return TRUE;
}
return FALSE;
}
///
/// "KillImage"
VOID KillImage(VOID)
{
if (MyImage)
FreeDiskObject(MyImage);
}
///
/// "ChangeIcon"
VOID ChangeIcon(VOID)
{
KillIcon();
KillImage();
switch (Active)
{
case NEW:
GetImage(HaveMail);
break;
case NONE:
case LOGIN:
GetImage(NoMail);
break;
}
AddIcon(MyPort, MyImage);
}
///
/// "DoInfo"
VOID DoInfo(VOID)
{
UMSMsgNum result = 0;
UMSSelectTags(MyUMSAccount, UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelUnset, (1L<<0)|(1L<<1)|(1L<<2),
TAG_DONE);
/******************************************************************
1. For all messages with
(GlobalFlags & (ReadAccess|PostPoned|Old)) == ViewAccess
set the local flag bit 0.
These are all NEW messages, which can be read by the user.
******************************************************************/
UMSSelectTags(MyUMSAccount, UMSTAG_SelMask, UMSUSTATF_ReadAccess | UMSUSTATF_PostPoned | UMSUSTATF_Old,
UMSTAG_SelMatch, UMSUSTATF_ReadAccess,
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelSet, (1L<<0),
TAG_DONE);
/*******************************************************************
2. For all messages with
Group == NULL (i.e. mail)
set the local flag bit 1.
These are all mail messages.
*******************************************************************/
UMSSelectTags(MyUMSAccount, UMSTAG_WGroup, NULL,
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelSet, (1L<<1),
UMSTAG_SelQuick, TRUE,
TAG_DONE);
/*******************************************************************
3. For all messages with
(LocalFlags & (Bit 0 and Bit 1)) == (Bit 0 and Bit 1)
set the local flag bit 2.
This operation builds the intersection set of operation 1 and 2,
thus setting the local flag bit 2 in all new mails, which are
addressed to the user.
******************************************************************/
result = UMSSelectTags(MyUMSAccount, UMSTAG_SelReadLocal, TRUE,
UMSTAG_SelMask, (1L<<0) | (1L<<1),
UMSTAG_SelMatch, (1L<<0) | (1L<<1),
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelSet, (1L<<2),
TAG_DONE);
UnreadMails = result;
}
///
/// "Compare"
VOID Compare(VOID)
{
if (UnreadMails)
{
if (Active != NEW || PrevUnreadMails != UnreadMails)
{
Active = NEW;
ChangeIcon();
}
if (UnreadMails > PrevUnreadMails)
if (*MailComName)
DoCommand(MailComName, MailComStack);
}
else
{
if (Active != NONE)
{
Active = NONE;
ChangeIcon();
}
}
PrevUnreadMails = UnreadMails;
}
///
/// "Parse"
STRPTR HelpTxt = "\nUMSMailMon V"VERSION" ©1994 Thomas Schwarz\n" \
" based on Sabot V1.7 by Scott Ellis\n\n" \
" NAME/A UMS username.\n" \
" PASSWORD/A UMS password.\n" \
" SERVER/K UMS servername.\n" \
" MA=MAIL/K Name of icon to be shown to indicate that you have some\n" \
" new mail (without \".info\" extension). Def: \"Filled\"\n" \
" NM=NOMAIL/K Name of icon to be shown to indicate that you have *no*\n" \
" new mail (without \".info\" extension). Def: \"Empty\"\n" \
" NO=NOTIFY/K Name of a file or directory to be monitored. Everytime\n" \
" this changes, a check for mail is done. Def: No checks\n" \
" TI=TIMER/K/N Number of seconds between mail checks. Def: No checks\n" \
" XPOS/K/N Horizontal icon position in pixels. Def: Free floating\n" \
" YPOS/K/N Vertical icon position in pixels. Def: Free floating\n" \
" CC=CLICKCOMMAND/K Command to be executed when AppIcon is double-clicked.\n" \
" CS=CLICKSTACK/K/N Stacksize which CLICKCOMMAND is to be run with. If\n" \
" CLICKCOMMAND was omitted, CLICKSTACK has no effect.\n" \
" MC=MAILCOMMAND/K Command to be executed when new mail arrives.\n" \
" MS=MAILSTACK/K/N Works according to CLICKSTACK, but for MAILCOMMAND.\n" \
" DC=DROPCOMMAND/K Command to be executed when icons are dropped on the\n" \
" AppIcon. This command is executed once for each icon\n" \
" dropped with the name of the icon appended to it.\n" \
" DS=DROPSTACK/K/N Works according to CLICKSTACK, but for DROPCOMMAND.\n\n";
BOOL Parse(LONG argc, STRPTR *argv)
{
struct RDArgs *rda;
LONG argumentarray[16] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
STRPTR *toolarrayindex, toolstringindex, template;
struct DiskObject *diskobject;
rda = AllocDosObjectTags(DOS_RDARGS, TAG_DONE);
rda->RDA_ExtHelp = HelpTxt;
if (argc == 0)
{
CurrentDir(WBStart->sm_ArgList->wa_Lock);
if (diskobject = GetDiskObject(WBStart->sm_ArgList->wa_Name))
{
for (toolarrayindex = diskobject->do_ToolTypes; *toolarrayindex; toolarrayindex++)
rda->RDA_Source.CS_Length += strlen(*toolarrayindex) + 1;
rda->RDA_Source.CS_Buffer = AllocVec(rda->RDA_Source.CS_Length + 1, MEMF_CLEAR);
toolstringindex = rda->RDA_Source.CS_Buffer;
for (toolarrayindex = diskobject->do_ToolTypes; *toolarrayindex; toolarrayindex++)
toolstringindex = stpcpy(stpcpy(toolstringindex, *toolarrayindex), " ");
*(toolstringindex-1) = '\n';
FreeDiskObject(diskobject);
}
template = "NAME/A,PASSWORD/A,SERVER/K,MA=MAIL/K,NM=NOMAIL/K,NO=NOTIFY/K,TI=TIMER/K/N,XPOS/K/N,YPOS/K/N,CC=CLICKCOMMAND/K,CS=CLICKSTACK/K/N,MC=MAILCOMMAND/K,MS=MAILSTACK/K/N,DC=DROPCOMMAND/K,DS=DROPSTACK/K/N,THROWAWAY/M";
}
else
template = "NAME/A,PASSWORD/A,SERVER/K,MA=MAIL/K,NM=NOMAIL/K,NO=NOTIFY/K,TI=TIMER/K/N,XPOS/K/N,YPOS/K/N,CC=CLICKCOMMAND/K,CS=CLICKSTACK/K/N,MC=MAILCOMMAND/K,MS=MAILSTACK/K/N,DC=DROPCOMMAND/K,DS=DROPSTACK/K/N";
if (rda = ReadArgs(template, argumentarray, rda))
{
strcpy(Name, (STRPTR)argumentarray[NAME]);
strcpy(Password, (STRPTR)argumentarray[PASSWORD]);
if (argumentarray[SERVER])
strcpy(Server, (STRPTR)argumentarray[SERVER]);
if (argumentarray[NOTIFY])
strcpy(Watch, (STRPTR)argumentarray[NOTIFY]);
if (argumentarray[MAIL])
strcpy(HaveMail, (STRPTR)argumentarray[MAIL]);
else
strcpy(HaveMail, "Filled");
if (argumentarray[NOMAIL])
strcpy(NoMail, (STRPTR)argumentarray[NOMAIL]);
else
strcpy(NoMail, "Empty");
if (argumentarray[TIMER])
Timer = *(ULONG *)argumentarray[TIMER];
if (argumentarray[XPOS])
XPos = *(ULONG *)argumentarray[XPOS];
else
XPos = NO_ICON_POSITION;
if (argumentarray[YPOS])
YPos = *(ULONG *)argumentarray[YPOS];
else
YPos = NO_ICON_POSITION;
if (argumentarray[CLICKCOMMAND])
strcpy(ClickComName, (STRPTR)argumentarray[CLICKCOMMAND]);
else
strcpy(ClickComName, "QUIT");
if (argumentarray[CLICKSTACK])
ClickComStack = *(ULONG *)argumentarray[CLICKSTACK];
if (argumentarray[MAILCOMMAND])
strcpy(MailComName, (STRPTR)argumentarray[MAILCOMMAND]);
if (argumentarray[MAILSTACK])
MailComStack = *(ULONG *)argumentarray[MAILSTACK];
if (argumentarray[DROPCOMMAND])
strcpy(DropComName, (STRPTR)argumentarray[DROPCOMMAND]);
if (argumentarray[DROPSTACK])
DropComStack = *(ULONG *)argumentarray[DROPSTACK];
}
else
{
PrintFault(IoErr(), NULL);
return FALSE;
}
FreeArgs(rda);
FreeVec(rda->RDA_Source.CS_Buffer);
FreeDosObject(DOS_RDARGS, rda);
return TRUE;
}
///
/// "DoCommand"
VOID DoCommand(STRPTR command, ULONG stack)
{
BPTR ofh, ifh;
if(!*command)
return;
if (ofh = Open("NIL:", MODE_READWRITE))
{
if (ifh = Open("NIL:", MODE_READWRITE))
{
if (SystemTags(command,
SYS_Input, ifh,
SYS_Output, ofh,
SYS_UserShell, DOSTRUE,
SYS_Asynch, DOSTRUE,
NP_StackSize, stack,
NP_CopyVars, DOSTRUE,
NP_Cli, DOSTRUE,
TAG_END) != -1)
return;
Close(ifh);
}
Close(ofh);
}
}
///
/// "MakeVars"
BOOL MakeVars(VOID)
{
if (HaveMail = AllocVec(9 * BIGSTRING, MEMF_CLEAR))
{
NoMail = HaveMail + BIGSTRING;
Watch = NoMail + BIGSTRING;
ClickComName = Watch + BIGSTRING;
MailComName = ClickComName + BIGSTRING;
DropComName = MailComName + BIGSTRING;
Name = DropComName + BIGSTRING;
Password = Name + BIGSTRING;
Server = Password + BIGSTRING;
return TRUE;
}
return FALSE;
}
///
/// "FreeVars"
VOID FreeVars(VOID)
{
if (HaveMail)
FreeVec(HaveMail);
}
///
/// "BeginNotify"
VOID BeginNotify(VOID)
{
if (MyNoteReq = AllocVec(sizeof(struct NotifyRequest), MEMF_CLEAR))
{
if ((MyNoteSigNum = AllocSignal(-1L)) != -1L)
{
MyNoteReq->nr_Name = Watch;
MyNoteReq->nr_Flags = NRF_SEND_SIGNAL;
MyNoteReq->nr_stuff.nr_Signal.nr_Task = (struct Task *)FindTask(NULL);
MyNoteReq->nr_stuff.nr_Signal.nr_SignalNum = MyNoteSigNum;
if ((StartNotify(MyNoteReq)) == DOSTRUE)
return;
FreeSignal(MyNoteSigNum);
MyNoteSigNum = -1L;
}
FreeVec(MyNoteReq);
MyNoteReq = NULL;
}
}
///
/// "OpenTimer"
BOOL OpenTimer(VOID)
{
struct MsgPort *timer_port = NULL;
if (timer_port = CreatePort(NULL, 0))
{
if (TimeReq = (struct timerequest *)CreateExtIO(timer_port, sizeof(struct timerequest)))
{
if (!OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)TimeReq, 0))
{
TimeReq->tr_node.io_Command = TR_ADDREQUEST;
TimeReq->tr_node.io_Flags = 0;
TimeReq->tr_node.io_Error = 0;
MyTimerSig = (1L << TimeReq->tr_node.io_Message.mn_ReplyPort->mp_SigBit);
TimeReq->tr_time.tv_secs = Timer;
TimeReq->tr_time.tv_micro = 0;
SendIO((struct IORequest *)TimeReq);
return TRUE;
}
TimeReq->tr_node.io_Device = 0;
}
DeletePort(timer_port);
}
return FALSE;
}
///
/// "CloseTimer"
VOID CloseTimer(VOID)
{
if (TimeReq)
{
if (TimeReq->tr_node.io_Device)
CloseDevice((struct IORequest *)TimeReq);
if (TimeReq->tr_node.io_Message.mn_ReplyPort)
DeletePort(TimeReq->tr_node.io_Message.mn_ReplyPort);
DeleteExtIO((struct IORequest *)TimeReq);
MyTimerSig = 0;
TimeReq = NULL;
}
}
///